package ro.qi.framework.sys.i18n.resources;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Locale;

import ro.qi.framework.sys.debug.Logger;
import ro.qi.framework.sys.i18n.resources.entities.Resource;
import ro.qi.framework.sys.i18n.resources.entities.ResourceCollection;

/*
 * @author George Pogorelschi
 *
 */
public class ResourcesManager {

	private static ResourcesManager instance = null;

	private Date lastUpdate = new Date();

	private Hashtable resourcesIds = null;
	private Hashtable resources = null;

	private ResourcesManager() {
	}

	public void init() {
		resourcesIds = new Hashtable();
		resources = new Hashtable();
		cacheDatabaseConfiguration();
	}

	public static synchronized ResourcesManager getInstance() {
		if( instance == null ) {
			instance = new ResourcesManager();
			instance.init();
		}
		return instance;
	}

	public void stop() {
		instance = null;
	}

	public static boolean isStarted() {
		return instance != null;
	}

	private void refreshResource(String resourceCode, int localeId, String resourceCaller) {
		Resource resource = new Resource(resourceCode, localeId);
		if( resource.getId() == 0 ) {
			Logger.error(this, "(" + resourceCaller + ") Resource with code " + resourceCode + " not found in database");
			return;
		}
		resources.put( resource.getCode(), resource);
		resourcesIds.put( new Integer(resource.getId()), resource.getCode());
	}

	private void refreshResource(int resourceId, int localeId) {
		Resource resource = new Resource(resourceId, localeId);
		if (resource.getId() == 0)
			return;
		resources.put(resource.getCode(), resource);
		resourcesIds.put(new Integer(resource.getId()), resource.getCode());
	}

//	public String getResource(String resourceName, String localeLanguage, String localeCountry, String localeVariant, String resourceCaller) {
//		return getResource(resourceName, LocaleCollection.getLocaleIdByLanguage(localeLanguage), resourceCaller);
//	}

	public String getResource(String resourceCode, int localeId, String resourceCaller) {
		if (!resources.containsKey(resourceCode))
			refreshResource(resourceCode, localeId, resourceCaller);
		if (!resources.containsKey(resourceCode) ) {
			StringBuffer buf = new StringBuffer();
			buf.append("<!-- resource \"");
			buf.append(resourceCode);
			buf.append("\" not found in database, locale id: ");
			buf.append(localeId);
			buf.append(" -->");
			return buf.toString();
		}

//		Resource resource = (Resource)resources.get(resourceName);
//		for (int i = 0; i < resource.getCollectionSize(); i++ ) {
//			if (resource.getValueLocaleId(i) == localeId)
//				return resource.getResourceValue(i);
//		}
		Resource resource = new Resource(((Resource)resources.get(resourceCode)).getId(), localeId);
		if (resource.getValue().length() > 0) {
			return resource.getValue(); 
		}

		StringBuffer buf = new StringBuffer();
		buf.append("<!-- resource \"");
		buf.append(resourceCode);
		buf.append("\" not found in database, locale id: ");
		buf.append(localeId);
		buf.append(" -->");
		return buf.toString();
	}

	private void cacheDatabaseConfiguration() {
		Logger.info(this, "Start caching resources");

		Calendar startTime = Calendar.getInstance();
		// retrieve resources
		ResourceCollection resourceCollection = new ResourceCollection();
		for( int idx = 0 ; idx < resourceCollection.getCollectionSize() ; idx++ ) {
			Resource resource = resourceCollection.getResource(idx);
			resources.put(resource.getCode(), resourceCollection.getResource(idx));
			resourcesIds.put(new Integer(resourceCollection.getId(idx)), resource.getCode());
		}
		Calendar endTime = Calendar.getInstance();

		double diff = endTime.getTime().getTime() - startTime.getTime().getTime();
		Logger.info(this, "End caching resources (" + diff + " ms)");
		Logger.info(this, "Readed:\t" + resources.size() + " resources");
	}

	public void checkForUpdates() {
		lastUpdate = new Date();

		try {
			// checks if there are any resources updated
			if (resourcesIds != null && resourcesIds.size() > 0) {
//				ResourceCollection res = ResourceCollection.selectByLastUpdate(lastUpdate);
				ResourceCollection res = new ResourceCollection();
				if (res != null) {
					for( int i = 0 ; i < res.getCollectionSize() ; i++ ) {
						Integer resId = new Integer(res.getId(i));
						if (resourcesIds.containsKey(resId) ) {
							String resourceName = (String)resourcesIds.get(resId);
							Resource resource = (Resource)resources.get(resourceName);
							Resource res1 = res.getResource(i);
							if (resource != null && resource.getUpdateTime() != null && res1.getUpdateTime().getTime() != resource.getUpdateTime().getTime()) {
								
								Logger.debug(this, "Resource " + resourceName + " was modified: " + DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ENGLISH).format(res1.getUpdateTime()));
//								refreshResource(res.getId(i));
							}
						}
					}
				}
			}
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}

}
